package com.system.manager.utils;

import com.baomidou.mybatisplus.extension.service.IService;
import com.system.manager.common.constant.SysConstants;
import com.system.manager.common.entity.ExclTemplate;
import com.system.manager.common.enums.ErrorCode;
import com.system.manager.common.enums.fileType.*;
import com.system.manager.common.exception.SysException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

// 导入pdf相关的包
import java.io.File;
import java.io.FileOutputStream;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;


/**
 * @program: HomeSchoolCommunication
 * @description:
 * @author: yxp
 * @create: 2021-08-28 16:34
 **/
public class FileUtil {

    private static final Logger log = LoggerFactory.getLogger(FileUtil.class);

    /**
     * 上传文件，并返回图片的路径
     *
     * @param file
     * @param filePath
     * @param fileName
     * @return
     * @throws Exception
     */
    public static String uploadFile(byte[] file, String filePath, String fileName) throws Exception {
        // 1.生成文件
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        // 2.根据目标文件的文件路径生成字符流
        FileOutputStream out = new FileOutputStream(filePath + fileName);
        
        FileWriter writer = new FileWriter(filePath + fileName);
        out.write(file);
        out.flush();
        out.close();
        // 3.设置返回的文件路径（这个路径是浏览器可以访问到的地址，而不是生成文件的filePath）
        filePath = SysConstants.SYS_FILE_STORE_PATH;

        return filePath + fileName;
    }

    /**
     * 导入excel文件
     *
     * @param file
     */
    public static boolean importExcel(MultipartFile file, ExclTemplate exclTemplate, IService service, Object entity) {

//        String filename = file.getOriginalFilename();
//        System.out.println(filename);
//        InputStream tps = (file.getInputStream());
//        final XSSFWorkbook tpWorkbook = new XSSFWorkbook(tps);
//        Sheet sheet = tpWorkbook.getSheetAt(0);
//        // 判断是否符合模板文件
//        boolean template = ExclFile.isSpecifyTemplate(exclTemplate, sheet);
//
//        // 不符合
//        if (!template) {
//            // 返回
//            return false;
//        }
//
//        // 符合，将文件内容插入到数据库中
//        for (int i = 0; i < exclTemplate.getTemplateContent().length; i++) {
//            Row row = sheet.getRow(i++);
//            if (row != null) {
//
//            }
//                student = new Student();
//                Cell studentId = row.getCell(0);
//                Cell sex = row.getCell(1);
//                Cell studentName = row.getCell(2);
//                Cell classId = row.getCell(3);
//                Cell phone = row.getCell(4);
//                student.setStudentId(studentId.getStringCellValue());
//                student.setSchoolId(schoolId);
//                student.setSex((int)sex.getNumericCellValue());
//                student.setStudentName(studentName.getStringCellValue());
//                student.setClassId((int)classId.getNumericCellValue());
//                student.setPhone(phone.getStringCellValue());
//                try {
//                    studentService.addStudent(student);
//                } catch (ClassesServiceException e) {
//                    e.printStackTrace();
//                    return Response.error();
//                } catch (SchoolServiceException | StudentServiceException e) {
//                    e.printStackTrace();
//                    return Response.error(e);
//                }
//            service.save(entity);
//        }

        return false;
    }

    /**
     * 判断当前的文件是否是正确的文件格式
     *
     * @param fileName
     * @return
     */
    public static boolean isValid(String fileName) {
        // 1.获取文件的后缀名
        String fileNameSuffix = getFileNameSuffix(fileName);

        // 2.判断文件名是否正确
        if (StringUtils.isEmpty(fileNameSuffix)) {
            return false;
        }

        // 3.判断文件是否是img txt excl文件类型的
        return ImageFile.ALL.isValid(fileNameSuffix) ||
                ExclFile.ALL.isValid(fileNameSuffix) ||
                TxtFile.ALL.isValid(fileNameSuffix)  ||
                VideoFile.ALL.isValid(fileNameSuffix);
    }


    /**
     * 判断文件格式是否是某一指定格式正确
     *
     * @param fileName
     * @param fileType
     * @return
     */
    public static boolean isSpecifyFormat(String fileName, FileType fileType) {
        // 1.获取文件的后缀名
        String fileNameSuffix = getFileNameSuffix(fileName);

        // 2.判断文件名是否正确
        if (StringUtils.isEmpty(fileNameSuffix)) {
            return false;
        }

        // 3.判断文件名是否是指定格式
        boolean equals = fileType.equals(fileNameSuffix);

        if (!equals) {
            return false;
        }

        log.info("--->文件合法");
        return true;
    }


    /**
     * 获取文件的后缀
     *
     * @param fileName
     * @return
     */
    public static String getFileNameSuffix(String fileName) {

        String fileNameSuffix = "";
        try {
            fileNameSuffix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
        } catch (Exception e) {
            log.info("--->文件非法");
        }
        return fileNameSuffix;
    }

    /**
     *
     * @param fileDir          模板html所在的位置
     * @param templateHtmlName 模板html的名字
     * @param param            需要显示在页面的参数，参数字段必须和html页面字段对应
     * @return                 返回pdf的存储路径
     * @throws Exception
     */
    public static String createPdf(String fileDir, String templateHtmlName, Map<String, Object> param) throws Exception {

        // 1.获取模板pdf页面,并将相关的信息渲染到页面
        String templateContent = getTemplateContent(fileDir, templateHtmlName, param);

        // 2.将pdf.html输出
        // 2.1 随机生成文件名
        String pdfName = UUIDUtils.randomUUID()+".pdf";

        html2Pdf(templateContent, SysConstants.SYS_OUT_DIR + pdfName);

        // 3.返回pdf存储的路径
        return SysConstants.SYS_FILE_STORE_PATH + pdfName;
    }

    /**
     * 生成pdf文件
     * @param args
     */
    /**
     * 获取模板内容
     * @param templateDirectory 模板文件夹
     * @param templateName      模板文件名
     * @param paramMap          模板参数,参数字段必须和html页面字段对应
     * @return
     * @throws Exception
     */
    private static String getTemplateContent(String templateDirectory, String templateName, Object paramMap) throws Exception {
        Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        try {
            configuration.setDirectoryForTemplateLoading(new File(templateDirectory));
        } catch (Exception e) {
            System.out.println("-- exception --");
            throw new SysException(ErrorCode.PDF_IS_VALID);
        }

        Writer out = new StringWriter();
        Template template = configuration.getTemplate(templateName,"UTF-8");
        template.process(paramMap, out);
        out.flush();
        out.close();
        return out.toString();
    }


    /**
     * HTML 转 PDF
     * @param content html内容
     * @param outPath           输出pdf路径
     * @return 是否创建成功
     */
    public static boolean html2Pdf(String content, String outPath) {
        try {
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outPath));
            document.open();
            XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                    new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"));
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("生成模板内容失败"+e.fillInStackTrace());
            throw new SysException(ErrorCode.PDF_IS_VALID);

        }
        return true;
    }
    /**
     * HTML 转 PDF
     * @param content html内容
     * @return PDF字节数组
     */
    public static byte[] html2Pdf(String content) {
        ByteArrayOutputStream outputStream = null;
        try {
            Document document = new Document();
            outputStream = new ByteArrayOutputStream();
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                    new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"));
            document.close();
        } catch (Exception e) {
            System.out.println("------生成pdf失败-------");
        }
        return outputStream.toByteArray();
    }

    public static void main(String[] args) throws Exception {
//        String fileNameSuffix = getFileNameSuffix("111111");
//        System.out.println(fileNameSuffix);

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        PdfTemplateTest paramMap = new PdfTemplateTest();
        paramMap.setDate_time(dateTimeFormatter.format(LocalDateTime.now()));
//        Map<String, Object> paramMap = new HashMap<>();
//
//        paramMap.put("date_time", dateTimeFormatter.format(LocalDateTime.now()));
//        paramMap.put("date", dateTimeFormatter.format(LocalDateTime.now()).substring(0, 10));
        // 输出的路径
        String outPath = "D:\\test.pdf";
        // 当前html文件所在位置
        String templateDirectory = "D:\\system-manager\\src\\main\\resources\\template\\layuimini\\page\\";
//        ClassLoader classLoader = FileUtil.class.getClassLoader();
//        URL resource = classLoader.getResource("resu");
//        System.out.println(resource.getPath());
//        String templateDirectory = resource.toURI().getPath();
//        System.out.println("当前模板文件所在的位置： " + templateDirectory);

        // 获取templateDirectory的输出流文件
        String templateContent = getTemplateContent(templateDirectory, "test_template.html", paramMap);
        // 进行pdf文件转换
        html2Pdf(templateContent, outPath);

    }
}
